package com.example.demo.netty.client.bio;

/**
 * @ClassName ModBusClient
 * @Description 用于测试Modbus协议
 * @Company inspur
 * @Author Kevin
 * @Date 2020/7/3 21:54
 * @Version 1.0
 */

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.ByteBuffer;


/**
 * 请求：
 *   30     03    00 08      00 01    01 E9
 * |地址码|功能码| 起始地址 | 寄存器数量 |CRC校验|
 *
 * 响应：
 *   30     03    00 02      27 AC    DE 0D
 * |地址码|功能码| 字节数   | 寄存器值  |CRC校验|
 *
 */

public class ModBusClient {
    //定义一个Socket对象
    static Socket socket = null;

    public static void main(String[] args) throws IOException {
        socket = new Socket("127.0.0.1", 8000);
        //读Socket里面的数据
        InputStream s = socket.getInputStream();
        OutputStream os = socket.getOutputStream();
        //构造输入
        byte[] request = new byte[]{0x30, 0x03, 0x00, 0x08, 0x00, 0x01, 0x01, (byte)0xE9};
        os.write(request);
        os.flush();
        //接收socket数据
        byte[] buf = new byte[128];
        int len = 0;
        len = s.read(buf);
        /**
         * 结果解析
         */
        //字节数
        int byteNum = ByteBuffer.wrap(buf, 2, 1).getInt();
        //寄存器值
        byte[] val = ByteBuffer.wrap(buf, 3, 2*byteNum).array();
        //CRC校验
        byte[] crcVal = ByteBuffer.wrap(buf, 3+2*byteNum, 2).array();

        System.out.println("寄存器数量" + byteNum);
        System.out.println("寄存器值" + bytesToHex(val));
        System.out.println("CRC校验"+ bytesToHex(crcVal));
    }

    //byte数组转化为16进制字符串输出
    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for ( int j = 0; j < bytes.length; j++ ) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }
    //也可以使用DatatypeConverter.parseHexBinary(helloHex);和DatatypeConverter.printHexBinary(helloBytes);
}
